/* $Id: ServiceDAOImpl.java 
 * Copyright (C) 2011, TRAKHEES
 *  
 * Revision History
 *
 * Date  			Author 		    	Remarks
 * ---------------------------------------------------------------------------------
 *
 */
package ae.pcfc.etks.online.common.dao.provider;

import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.criterion.Subqueries;
import org.springframework.stereotype.Repository;

import ae.pcfc.etks.online.common.ConstantsCommon;
import ae.pcfc.etks.online.common.ConstantsCommon.RequestType;
import ae.pcfc.etks.online.common.dao.ServiceDAO;
import ae.pcfc.etks.online.common.domain.AppMetaData;
import ae.pcfc.etks.online.common.domain.Service;
import ae.pcfc.etks.online.common.domain.ServiceReq;
import ae.pcfc.etks.online.common.domain.ServiceRole;
import ae.pcfc.etks.online.common.vo.PagingVO;

@Repository
public class ServiceDAOImpl extends BaseDAO implements ServiceDAO {

	/**
	 * add
	 * 
	 * @see ae.pcfc.etks.online.common.dao.ServiceDAO#add(ae.pcfc.etks.online.common.domain.Service)
	 * 
	 */
	public boolean add(Service services) {

		getHibernateTemplate().getSessionFactory().getCurrentSession().save(services);
		return true;
	}

	/**
	 * getServicesList
	 * 
	 * @see ae.pcfc.etks.online.common.dao.ServiceDAO#getServicesList()
	 * 
	 */
	@SuppressWarnings("unchecked")
	public List<Service> getServicesList() {

		Criteria criteria = getHibernateTemplate().getSessionFactory().getCurrentSession().createCriteria(Service.class);
		criteria.add(Restrictions.eq("serviceStatus", "A"));
		
		List<Service> list = criteria.list();
		if (list != null && list.size() > 0)
			return list;
		else
			return null;

	}

	/**
	 * getServiceByPrimaryKey
	 * 
	 * @see ae.pcfc.etks.online.common.dao.ServiceDAO#getServiceByPrimaryKey(java.lang.Long)
	 * 
	 */
	public Service getServiceByPrimaryKey(Long Id) {

		Criteria criteria = getHibernateTemplate().getSessionFactory().getCurrentSession().createCriteria(Service.class, "service");
		criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
		criteria.add(Restrictions.eq("service.serviceId", Id));
		/*criteria.createAlias("service.serviceAttrs", "serviceAttrs");
		criteria.add(Restrictions.eq("serviceAttrs.serviceAttrStatus", ConstantsCommon.ACTIVE).ignoreCase());*/

		@SuppressWarnings("unchecked")
		List<Service> list = criteria.list();
		if (list != null && list.size() > 0)
			return list.get(0);
		else
			return null;
	}

	/**
	 * deleteServiceById
	 * 
	 * @see ae.pcfc.etks.online.common.dao.ServiceDAO#deleteServiceById(java.lang.Long)
	 * 
	 */
	public boolean deleteServiceById(Long Id) {
		Session sess = getHibernateTemplate().getSessionFactory().getCurrentSession();
		Service onlineService = (Service) sess.load(Service.class, Id);
		sess.delete(onlineService);
		return true;

	}

	/**
	 * findServiceByServiceRoleIds
	 * 
	 * @see ae.pcfc.etks.online.common.dao.ServiceDAO#findServiceByServiceRoleIds(java.util.List, java.lang.String)
	 * 
	 */
	public List<Service> findServiceByServiceRoleIds(List<Long> serviceRoleIds, String strDefault) {

		Criteria criteria = getHibernateTemplate().getSessionFactory().getCurrentSession()
				.createCriteria(Service.class, "service");
		
		criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

		if (strDefault != null)
			criteria.add(Restrictions.eq("serviceDefault", strDefault));

		criteria.createAlias("service.serviceRoles", "serviceRole");
		criteria.add(Restrictions.in("serviceRole.roleId", serviceRoleIds));

		@SuppressWarnings("unchecked")
		List<Service> list = (List<Service>) criteria.list();

		return list == null ? null : list;
	}

	/**
	 * findServiceAvailableByUserNameAndRoleIds
	 * 
	 * @see ae.pcfc.etks.online.common.dao.ServiceDAO#findServiceAvailableByUserNameAndRoleIds(java.lang.String, java.util.List)
	 * 
	 */
	public List<Service> findServiceAvailableByUserNameAndRoleIds(String userName, List<Long> roleIds) {

		Criteria criteria = getHibernateTemplate().getSessionFactory().getCurrentSession()
				.createCriteria(Service.class, "service");
		
		criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
		
		criteria.createAlias("service.serviceRoles", "serviceRoles");
		// On the basis of Client Roles fetch the services
		criteria.add(Restrictions.in("serviceRoles.roleId", roleIds));
		
		/************** Sub Criteria for the services which are already registered *****************/
		DetachedCriteria subCriteria = DetachedCriteria.forClass(ServiceRole.class, "serviceRole");
		subCriteria.setProjection(Projections.property("serviceRole.service.serviceId"));
		subCriteria.createAlias("serviceRole.userServiceSecurities", "serviceSecurity");
		subCriteria.add(Restrictions.eq("serviceSecurity.usSecurityUsername", userName));
		// Setting for the services which are already registered exclude them
		criteria.add(Subqueries.propertyNotIn("service.serviceId", subCriteria));
		/************** End Sub Criteria for the services which are already registered ************/
		
		
		/************** Sub Criteria for the services which are already requested *****************/
		DetachedCriteria alreadyRequsted = DetachedCriteria.forClass(ServiceReq.class, "serviceReq");
		alreadyRequsted.setProjection(Projections.property("serviceReq.service.serviceId"));
		alreadyRequsted.createAlias("serviceReq.user", "user");
		alreadyRequsted.add(Restrictions.eq("user.UUsername", userName));
		
		/************** Sub Criteria for the Service appln which are already requested and rejected *****************/
		DetachedCriteria appMetaDataRequsted = DetachedCriteria.forClass(AppMetaData.class, "appMetaData");
		appMetaDataRequsted.setProjection(Projections.property("appMetaData.applicationId"));
		appMetaDataRequsted.add(Restrictions.like("appMetaData.clientRefNo", RequestType.SERVICE.getCode()+"%"));
		appMetaDataRequsted.add(Restrictions.ne("appMetaData.wfStatus", ConstantsCommon.REJECT));
		
		
		// Setting for the  Service appln  which are already registered and rejected exclude them
		alreadyRequsted.add(Subqueries.propertyIn("serviceReq.applicationId", appMetaDataRequsted));		
		
		// Setting for the services which are already registered exclude them
		criteria.add(Subqueries.propertyNotIn("service.serviceId", alreadyRequsted));
		/************** End Sub Criteria for the services which are already requested **************/
		
		criteria.add(Restrictions.eq("service.serviceStatus", "A"));
		
		@SuppressWarnings("unchecked")
		List<Service> serviceList = criteria.list();

		return (serviceList != null && serviceList.size() > 0) ? serviceList : null;

	}

	/**
	 * findServiceByPrimaryKey
	 * 
	 * @see ae.pcfc.etks.online.common.dao.ServiceDAO#findServiceByPrimaryKey(java.lang.Long)
	 * 
	 */
	public Service findServiceByPrimaryKey(Long id) {
		//return (Service) getHibernateTemplate().getSessionFactory().getCurrentSession().get(Service.class, id);
		Criteria criteria = getHibernateTemplate().getSessionFactory().getCurrentSession()
				.createCriteria(Service.class, "service");
		criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
		criteria.add(Restrictions.eq("service.serviceId", id));
		/*criteria.createAlias("service.serviceAttrs", "serviceAttrs");
		criteria.add(Restrictions.eq("serviceAttrs.serviceAttrStatus", ConstantsCommon.ACTIVE).ignoreCase());*/
		criteria.add(Restrictions.eq("service.serviceStatus", "A"));
		
		@SuppressWarnings("unchecked")
		List<Service> list = criteria.list();
		if (list != null && list.size() > 0)
			return list.get(0);
		else
			return null;

	}

	/**
	 * findServiceListByIds
	 * 
	 * @see ae.pcfc.etks.online.common.dao.ServiceDAO#findServiceListByIds(java.util.List)
	 * 
	 */
	public List<Service> findServiceListByIds(List<Long> ids) {

		Criteria criteria = getHibernateTemplate().getSessionFactory().getCurrentSession()
				.createCriteria(Service.class, "service");
		criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
		criteria.add(Restrictions.in("service.serviceId", ids));
		/*criteria.createAlias("service.serviceAttrs", "serviceAttrs");
		criteria.add(Restrictions.eq("serviceAttrs.serviceAttrStatus", ConstantsCommon.ACTIVE).ignoreCase());*/
		criteria.add(Restrictions.eq("service.serviceStatus", "A"));

		@SuppressWarnings("unchecked")
		List<Service> list = (List<Service>) criteria.list();

		return list == null ? null : list;
	}

	/**
	 * findServiceListByUserName
	 * 
	 * @see ae.pcfc.etks.online.common.dao.ServiceDAO#findServiceListByUserName(java.lang.String)
	 * 
	 */
	public List<Service> findServiceListByUserName(String userName) {

		Criteria criteria = getHibernateTemplate().getSessionFactory().getCurrentSession()
				.createCriteria(Service.class, "service");
		criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

		criteria.createAlias("service.serviceRoles", "serviceRoles");
		criteria.createAlias("serviceRoles.userServiceSecurities", "userServiceSecurities");

		criteria.add(Restrictions.eq("userServiceSecurities.usSecurityUsername", userName).ignoreCase());
		criteria.add(Restrictions.eq("service.serviceStatus", "A"));

		@SuppressWarnings("unchecked")
		List<Service> serviceList = criteria.list();

		return (serviceList != null && serviceList.size() > 0) ? serviceList : null;
	}

	/**
	 * delete
	 * 
	 * @see ae.pcfc.etks.online.common.dao.ServiceDAO#delete(ae.pcfc.etks.online.common.domain.Service)
	 * 
	 */
	public void delete(Service service) {

		getHibernateTemplate().getSessionFactory().getCurrentSession().delete(service);

	}

	/**
	 * findUserDefaultService
	 * 
	 * @see ae.pcfc.etks.online.common.dao.ServiceDAO#findUserDefaultService()
	 * 
	 */
	public Service findUserDefaultService() {

		Criteria criteria = getHibernateTemplate().getSessionFactory().getCurrentSession().createCriteria(Service.class);
		criteria.add(Restrictions.eq("serviceDefault", "UD"));
		@SuppressWarnings("unchecked")
		List<Service> list = criteria.list();
		if (list != null && list.size() > 0)
			return list.get(0);
		else
			return null;
	}

	/**
	 * findServiceByServiceDefault
	 * 
	 * @see ae.pcfc.etks.online.common.dao.ServiceDAO#findServiceByServiceDefault(java.lang.String)
	 * 
	 */
	public Service findServiceByServiceDefault(String strServiceDefault) {

		Criteria criteria = getHibernateTemplate().getSessionFactory().getCurrentSession().createCriteria(Service.class);
		criteria.add(Restrictions.eq("serviceDefault", strServiceDefault));
		@SuppressWarnings("unchecked")
		List<Service> list = criteria.list();
		if (list != null && list.size() > 0)
			return list.get(0);
		else
			return null;
	}

	/**
	 * getServicesListByPagingVO
	 * 
	 * @see ae.pcfc.etks.online.common.dao.ServiceDAO#getServicesListByPagingVO(ae.pcfc.etks.online.common.vo.PagingVO)
	 * 
	 */
	public List<Service> getServicesListByPagingVO(PagingVO pagingVO) {

		Criteria criteria = getHibernateTemplate().getSessionFactory().getCurrentSession().createCriteria(Service.class);

		criteria.add(Restrictions.eq("serviceStatus", "A"));

		if (pagingVO != null) {
			
			if (pagingVO.getSearchfieldName() != null && pagingVO.getSerachString() != null
					&& StringUtils.isNotBlank(pagingVO.getSerachString())) {

				if (pagingVO.getSearchfieldName().equals("serviceId")) {
					criteria.add(Restrictions.eq(pagingVO.getSearchfieldName(), Long.parseLong(pagingVO.getSerachString())));

				} else {

					criteria.add(Restrictions.eq(pagingVO.getSearchfieldName(), pagingVO.getSerachString()));
				}
			}

			if (pagingVO.getSortFieldName() != null && pagingVO.getSortOrder() != null) {

				if (pagingVO.getSortOrder().equals("asc")) {

					criteria.addOrder(Order.asc(pagingVO.getSortFieldName()));

				} else if (pagingVO.getSortOrder().equals("desc")) {

					criteria.addOrder(Order.desc(pagingVO.getSortFieldName()));
				}
			}

			if (pagingVO.getStart() != null)
				criteria.setFirstResult(pagingVO.getStart());

			if (pagingVO.getPageSize() != null)
				criteria.setMaxResults(pagingVO.getPageSize());
		}

		@SuppressWarnings("unchecked")
		List<Service> list = criteria.list();

		if (list != null && list.size() > 0)
			return list;
		else
			return null;
	}

	/**
	 * udpate
	 * 
	 * @see ae.pcfc.etks.online.common.dao.ServiceDAO#udpate(ae.pcfc.etks.online.common.domain.Service)
	 * 
	 */
	public void udpate(Service service) {
		
		getHibernateTemplate().getSessionFactory().getCurrentSession().merge(service);
		
	}
}
